<template>
  <div v-loading="loading" class="code_custom_field" element-loading-text="加载中...">
    <div class="header">
      <div class="btn_group">
        <HPlainButton @click="addField"> 添加字段</HPlainButton>
        <el-dropdown trigger="click">
          <HButton :disabled="selecttion.length == 0">
            批量操作
            <el-icon class="el-icon--right">
              <ArrowDown />
            </el-icon>
          </HButton>
          <template #dropdown>
            <el-dropdown-menu>
              <el-dropdown-item @click="changeAll(1)">
                <el-icon>
                  <CircleCheck />
                </el-icon>
                批量启用
              </el-dropdown-item>
              <el-dropdown-item @click="changeAll(2)">
                <el-icon>
                  <Warning />
                </el-icon>
                批量禁用
              </el-dropdown-item>
              <el-dropdown-item @click="changeAll(3)">
                <el-icon>
                  <Delete />
                </el-icon>
                批量删除
              </el-dropdown-item>
            </el-dropdown-menu>
          </template>
        </el-dropdown>
        <el-dropdown trigger="click">
          <HButton :disabled="selecttion.length == 0">
            批量显示
            <el-icon class="el-icon--right">
              <ArrowDown />
            </el-icon>
          </HButton>
          <template #dropdown>
            <el-dropdown-menu>
              <el-dropdown-item @click="changeAll(4)">
                <el-icon>
                  <Switch />
                </el-icon>
                开启列表查询
              </el-dropdown-item>
              <el-dropdown-item @click="changeAll(5)">
                <el-icon>
                  <Switch />
                </el-icon>
                关闭列表查询
              </el-dropdown-item>
              <el-dropdown-item @click="changeAll(6)">
                <el-icon>
                  <Switch />
                </el-icon>
                开启列表显示
              </el-dropdown-item>
              <el-dropdown-item @click="changeAll(7)">
                <el-icon>
                  <Switch />
                </el-icon>
                关闭列表显示
              </el-dropdown-item>
              <el-dropdown-item @click="changeAll(8)">
                <el-icon>
                  <Switch />
                </el-icon>
                开启移动端显示
              </el-dropdown-item>
              <el-dropdown-item @click="changeAll(9)">
                <el-icon>
                  <Switch />
                </el-icon>
                关闭移动端显示
              </el-dropdown-item>
            </el-dropdown-menu>
          </template>
        </el-dropdown>
      </div>
      <div class="search">
        <el-select
          v-model="form.type"
          style="width: 140px"
          placeholder="选择字段类型"
          filterable
          clearable
          @change="getList"
          @clear="getList"
        >
          <el-option
            v-for="item in options"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          />
        </el-select>
        <el-input
          v-model.trim="name"
          placeholder="字段名称"
          style="width: 100px"
          clearable
          @keyup.enter="getList"
          @clear="getList"
        />
        <HButton type="primary" @click="getList">
          <el-icon>
            <Search />
          </el-icon>
          搜索
        </HButton>
        <HButton @click="clearValue">
          <el-icon>
            <RefreshRight />
          </el-icon>
          重置
        </HButton>
      </div>
    </div>
    <div class="table">
      <el-table
        ref="tableDom"
        border
        stripe
        resizable
        :data="tableData"
        height="100%"
        @selection-change="handleChange"
      >
        <el-table-column type="selection" width="40" fixed />
        <el-table-column
          show-overflow-tooltip
          type="index"
          :index="indexMethod"
          label="序号"
          width="50"
          fixed="left"
          :align="'center'"
        />
        <el-table-column show-overflow-tooltip prop="name" label="字段名称" width="150" />
        <el-table-column show-overflow-tooltip prop="required" label="是否必填" width="80">
          <template #default="scope">
            <span v-if="scope.row.required">必填</span>
            <span v-else>选填</span>
          </template>
        </el-table-column>
        <el-table-column show-overflow-tooltip prop="type" label="字段类型" width="120">
          <template #default="{ row }">
            {{ getFieldTypeText(row.type) }}
          </template>
        </el-table-column>
        <el-table-column show-overflow-tooltip prop="content" label="字段内容" min-width="120" />
        <el-table-column show-overflow-tooltip prop="listCondition" label="支持查询" width="100">
          <template #default="scope">
            <div class="flex-center" style="display: flex; align-items: center; gap: 7px">
              <el-switch
                v-model="scope.row.listCondition"
                :before-change="beforeSwitchChange"
                @change="changeShow(scope.row.listCondition, scope)"
              />
              <span v-if="scope.row.listCondition">显示</span>
              <span v-else>隐藏</span>
            </div>
          </template>
        </el-table-column>
        <el-table-column show-overflow-tooltip prop="listShow" label="列表显示" width="100">
          <template #default="scope">
            <div class="flex-center" style="display: flex; align-items: center; gap: 7px">
              <el-switch
                v-model="scope.row.listShow"
                :before-change="beforeSwitchChange"
                @change="changeShow(scope.row.listShow, scope)"
              />
              <span v-if="scope.row.listShow">显示</span>
              <span v-else>隐藏</span>
            </div>
          </template>
        </el-table-column>
        <el-table-column show-overflow-tooltip prop="mobileShow" label="移动端显示" width="100">
          <template #default="scope">
            <div class="flex-center" style="display: flex; align-items: center; gap: 7px">
              <el-switch
                v-model="scope.row.mobileShow"
                :before-change="beforeSwitchChange"
                @change="changeShow(scope.row.mobileShow, scope)"
              />
              <span v-if="scope.row.mobileShow">显示</span>
              <span v-else>隐藏</span>
            </div>
          </template>
        </el-table-column>
        <el-table-column show-overflow-tooltip prop="uploadSize" label="最大尺寸" width="100" />
        <el-table-column show-overflow-tooltip prop="uploadQty" label="上传数量" width="100" />
        <el-table-column show-overflow-tooltip prop="tip" label="提示信息" width="150" />
        <el-table-column prop="status" label="状态" width="70" fixed="right" :align="'center'">
          <template #default="scope">
            <div class="flex_jsutify_cennter">
              <HStatus v-if="scope.row.status" type="info">禁用</HStatus>
              <HStatus v-else>启用</HStatus>
            </div>
          </template>
        </el-table-column>
        <el-table-column fixed="right" label="操作" width="90">
          <template #default="scope">
            <h-space>
              <HLink @click="editField(scope.row.id)">编辑</HLink>
              <h-link type="error" @click="handleDelCodeSet(scope.row)">删除</h-link>
            </h-space>
          </template>
        </el-table-column>
      </el-table>
    </div>
    <div class="pagination">
      <Pagination
        ref="pagination"
        :list_total="total"
        @size-change="getList"
        @current-change="getList(false)"
      />
    </div>
    <!-- 添加/编辑  字段弹窗 -->
    <h-drawer
      v-model="addDialog"
      :width="700"
      unit="px"
      :title="fieldTitle"
      :loading="fieldLoading"
    >
      <el-form
        ref="formRef"
        label-position="top"
        inline-message
        class="modal_form_content"
        :rules="rules"
        :model="form"
      >
        <!-- 字段名称 -->
        <el-form-item label="字段名称" prop="name">
          <el-input v-model.trim="form.name" clearable placeholder="请输入名称" />
        </el-form-item>

        <!-- 字段类型 -->
        <el-form-item label="字段类型">
          <el-select v-model="form.type">
            <el-option
              v-for="(item, index) in options"
              :key="index"
              :label="item.label"
              :value="item.value"
            >
            </el-option>
          </el-select>
        </el-form-item>

        <!-- 提示信息 -->
        <el-form-item label="提示信息">
          <el-input v-model.trim="form.tip" clearable placeholder="请输入提示信息" />
        </el-form-item>

        <div class="same_line" style="column-gap: 32px">
          <!-- 是否必填 -->
          <el-form-item label="是否必填" class="same_line">
            <el-radio-group v-model="form.required">
              <el-radio :value="false" size="small">选填</el-radio>
              <el-radio :value="true" size="small">可填</el-radio>
            </el-radio-group>
          </el-form-item>

          <!-- 字段状态 -->
          <el-form-item label="字段状态" class="same_line">
            <el-radio-group v-model="form.status">
              <el-radio :value="false" size="small">启用</el-radio>
              <el-radio :value="true" size="small">禁用</el-radio>
            </el-radio-group>
          </el-form-item>
        </div>

        <div class="same_line" style="column-gap: 32px; flex-wrap: wrap; row-gap: 12px">
          <!-- 支持查询 -->
          <el-form-item label="支持查询" class="same_line">
            <el-radio-group v-model="form.listCondition">
              <el-radio :value="true" size="small">是</el-radio>
              <el-radio :value="false" size="small">否</el-radio>
            </el-radio-group>
          </el-form-item>

          <!-- 列表显示 -->
          <el-form-item label="列表显示" class="same_line">
            <el-radio-group v-model="form.listShow">
              <el-radio :value="true" size="small">是</el-radio>
              <el-radio :value="false" size="small">否</el-radio>
            </el-radio-group>
          </el-form-item>

          <!-- 移动端显示 -->
          <el-form-item label="移动端显示" class="same_line">
            <el-radio-group v-model="form.mobileShow">
              <el-radio :value="true" size="small">是</el-radio>
              <el-radio :value="false" size="small">否</el-radio>
            </el-radio-group>
          </el-form-item>
        </div>

        <template v-if="form.type == 3 || form.type == 4">
          <template v-for="(item, index) in form.contentVos" :key="index">
            <!-- 字段内容 -->
            <el-form-item props="val" :rules="rules.val" :label="`字段内容${index + 1}`">
              <div class="field_content">
                <el-input
                  v-model.trim="item.val"
                  clearable
                  placeholder="请输入字段内容"
                  maxlength="20"
                />
                <div class="btn_group">
                  <h-link
                    v-if="form.contentVos.length > 1"
                    type="error"
                    @click="handleDele(index, item)"
                    >删除</h-link
                  >
                  <h-link v-if="index === 0" @click="addText">添加</h-link>
                </div>
              </div>
            </el-form-item>
          </template>
        </template>

        <!-- 最大尺寸 -->
        <el-form-item
          v-if="form.type == 5 || form.type == 6 || form.type == 7"
          label="最大尺寸(MB)"
          prop="uploadSize"
        >
          <el-input
            v-model.trim="form.uploadSize"
            type="number"
            clearable
            placeholder="请输入最大尺寸"
            @input="limitNum(form.uploadSize, 100)"
            @change="form.uploadSize ? '' : (form.uploadSize = 1)"
          />
        </el-form-item>

        <!-- 上传数量 -->
        <el-form-item
          v-if="form.type == 5 || form.type == 6 || form.type == 7"
          label="上传数量"
          class="form-item"
          prop="uploadQty"
        >
          <el-input
            v-model.trim="form.uploadQty"
            type="number"
            clearable
            placeholder="请输入数量"
            @input="limitNum(form.uploadQty, 10)"
            @change="form.uploadQty ? '' : (form.uploadQty = 1)"
          />
        </el-form-item>
      </el-form>

      <template #footer>
        <HButton is-modal type="primary" @click="saveData(formRef)">保存</HButton>
        <HButton is-modal @click="addDialog = false">取消</HButton>
      </template>
    </h-drawer>
  </div>
</template>

<script setup lang="ts">
  import Pagination from '../../../../../../../components/Pagination/index.vue'
  import { ref, reactive } from 'vue'
  import type { FormInstance, TableInstance } from 'element-plus'
  import { ElMessage, ElMessageBox } from 'element-plus'
  import {
    Search,
    Delete,
    Warning,
    RefreshRight,
    Switch,
    CircleCheck,
    ArrowDown,
  } from '@element-plus/icons-vue'
  import {
    getFieldList,
    saveField,
    getInfo,
    disableField,
    deleteField,
    listConditionField,
    listShowField,
    mobileShowField,
  } from '@/api/basic'
  import { CodeSet } from './types'

  const handleDelCodeSet = (codeSet: CodeSet) => {
    if (tableDom.value) {
      tableDom.value.toggleRowSelection(codeSet, true)
      changeAll(3)
    }
  }

  //列表序号
  const indexMethod = (index: number) => {
    return (index + 1) * 1
  }

  const name = ref('') // 字段名称
  const tableData = ref([]) // 列表数据
  const tableDom = ref<TableInstance | null>(null) // 列表dom

  const pagination = ref() // 分页dom
  const total = ref(0) // 总数目

  const addDialog = ref(false)
  const loading = ref(false)
  const options = ref([
    {
      value: 1,
      label: '文本',
    },
    {
      value: 2,
      label: '多行文本',
    },
    {
      value: 3,
      label: '单选',
    },
    {
      value: 4,
      label: '多选',
    },
    {
      value: 5,
      label: '多图',
    },
    {
      value: 6,
      label: '附件',
    },
    {
      value: 7,
      label: '视频',
    },
    {
      value: 8,
      label: '评分',
    },
    {
      value: 9,
      label: '日期',
    },
    {
      value: 10,
      label: '日期时间',
    },
  ])

  const fieldTitle = ref('')
  const fieldLoading = ref(false)

  const form = reactive({
    id: null,
    category: 2,
    contentVos: [{ id: null, val: '' }],
    delContentVoIds: [],
    listCondition: true,
    listShow: true,
    uploadSize: null,
    mobileShow: true,
    name: '',
    required: false,
    status: false,
    tip: '',
    type: null,
    uploadQty: null,
  })

  // 表单元素
  const formRef = ref<FormInstance>()
  const fieldFormRef = ref<FormInstance>()

  // 验证规则
  const rules = reactive({
    name: [{ required: true, message: '请输入字段名称', trigger: 'blur' }],
    val: [{ required: true, message: '请输入字段内容', trigger: 'blur' }],
    status: [{ required: true, message: '请选择状态', trigger: 'blur' }],
    required: [{ required: true, message: '请选择状态', trigger: 'blur' }],
    uploadSize: [
      { required: false, message: '请输入最大尺寸', trigger: 'blur' },
      {
        pattern: /^[+]{0,1}(\d+)$/g,
        message: '格式错误',
        trigger: 'blur',
      },
    ],
    uploadQty: [
      { required: false, message: '请输入上传数量', trigger: 'blur' },
      {
        pattern: /^[+]{0,1}(\d+)$/g,
        message: '格式错误',
        trigger: 'blur',
      },
    ],
  })

  /**
   * 根据字段类型获取对应的文本
   * @param {Number} type - 字段类型
   */
  const getFieldTypeText = (type: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10) => {
    if (type === 1) {
      return '文本'
    }

    if (type === 2) {
      return '多行文本'
    }

    if (type === 3) {
      return '单选'
    }

    if (type === 4) {
      return '多选'
    }

    if (type === 5) {
      return '多图'
    }

    if (type === 6) {
      return '附件'
    }

    if (type === 7) {
      return '视频'
    }

    if (type === 8) {
      return '评分'
    }

    if (type === 9) {
      return '日期'
    }

    if (type === 10) {
      return '日期时间'
    }
  }

  const limitNum = (val, n) => {
    if (val > n) {
      val = n
    } else if (val == 0 && val != '') {
      val = 1
    }
    if (n == 100) {
      form.uploadSize = val
    } else {
      form.uploadQty = val
    }
  }
  interface switchType {
    switchStatus: boolean
  }

  let switchState = reactive<switchType>({
    switchStatus: false,
  })
  // 重置搜索
  const clearValue = () => {
    form.type = null
    name.value = ''
    getList()
  }

  // 获取请求数据
  const getData = (val) => {
    if (val) pagination.value.setPage()
    return {
      category: 2,
      limit: pagination.value.size,
      name: name.value,
      page: pagination.value.current,
      type: null,
    }
  }

  // 获取列表数据
  const getList = async (val = true) => {
    await getFieldList(getData(val)).then((res) => {
      tableData.value = res.data.data.rows
      total.value = parseInt(res.data.data.total)
    })
  }

  // 获取表格选中的数据
  const selecttion = ref([])
  const handleChange = (val: any[]) => {
    if (val.length != 0) {
      val.forEach((item: { id: any }) => {
        if (Object.values(selecttion.value).indexOf(item.id) == -1) {
          selecttion.value.push(item.id)
        } else {
          selecttion.value = selecttion.value.filter((i) => i == item.id)
        }
      })
    } else {
      selecttion.value = []
    }
  }

  // 新增字段内容
  const addText = () => {
    form.contentVos.push({ id: null, val: '' })
  }

  // 删除字段内容
  const handleDele = (index, obj) => {
    form.contentVos.splice(index, 1)
    if (obj.id) {
      form.delContentVoIds.push(obj.id)
    }
  }

  // 添加字段
  const addField = () => {
    fieldTitle.value = '添加字段'
    addDialog.value = true
    form.id = null
    form.type = null
    form.contentVos = [{ id: null, val: '' }]
    form.delContentVoIds = []
    form.listCondition = true
    form.listShow = true
    form.mobileShow = true
    form.name = ''
    form.required = false
    form.status = false
    form.tip = ''
    ;(form.uploadQty = 10), (form.uploadSize = 100)
  }

  // 编辑字段
  const editField = async (id) => {
    fieldTitle.value = '编辑字段'
    addDialog.value = true
    fieldLoading.value = true
    form.delContentVoIds = []
    await getInfo(id).then((res) => {
      fieldLoading.value = false
      form.id = res.data.data.row.id
      form.type = res.data.data.row.type
      if (res.data.data.row.contentVos.length == 0) {
        form.contentVos = [{ id: null, val: '' }]
      } else {
        form.contentVos = res.data.data.row.contentVos
      }
      form.listCondition = res.data.data.row.listCondition
      form.listShow = res.data.data.row.listShow
      form.uploadSize = res.data.data.row.uploadSize
      form.mobileShow = res.data.data.row.mobileShow
      form.name = res.data.data.row.name
      form.required = res.data.data.row.required
      form.status = res.data.data.row.status
      form.tip = res.data.data.row.tip
      form.uploadQty = res.data.data.row.uploadQty
    })
  }

  // 保存的方法
  const saveMethod = (method, data, dialog, load) => {
    load.value = true
    method(data).then((res) => {
      if (res.data.success == true) {
        ElMessage({
          message: res.data.message,
          type: 'success',
          duration: 5000,
          plain: true,
          showClose: true,
        })
        dialog.value = false
        load.value = false
        getList()
      } else {
        ElMessage({
          message: res.data.message,
          type: 'warning',
          duration: 5000,
          plain: true,
          showClose: true,
        })
        load.value = false
        return
      }
    })
  }

  // 保存字段
  const saveData = (formEl: FormInstance | undefined) => {
    formEl.validate((valid) => {
      if (valid) {
        if (form.contentVos.length != 0) {
          form.contentVos.forEach((item) => {
            if (item?.id) {
              form.delContentVoIds.push(item?.id)
            }
          })
        }
        saveMethod(saveField, form, addDialog, fieldLoading)
      }
    })
  }

  // 批量操作的方法
  const changeMethod = (type, method, arr, status, dialog, obj) => {
    if (arr.length == 0) {
      ElMessage({
        message: `请选择要${type}的字段`,
        type: 'warning',
        duration: 5000,
        plain: true,
        showClose: true,
      })
      return
    }
    ElMessageBox({
      type: type === '删除' ? 'error' : 'warning',
      title: '提示',
      message: `确认${type}选中的字段?`,
      showCancelButton: true,
      closeOnClickModal: false,
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      autofocus: false,
      beforeClose: (action, instance, done) => {
        if (action === 'confirm') {
          instance.confirmButtonLoading = true
          instance.confirmButtonText = '加载中...'
          setTimeout(() => {
            done()
            setTimeout(() => {
              instance.confirmButtonLoading = false
            }, 0)
          }, 1000)
        } else {
          done()
        }
      },
    })
      .then(async () => {
        if (status != 3) {
          await method(arr, status).then((res) => {
            ElMessage({
              message: res.data.message,
              type: 'success',
              duration: 5000,
              plain: true,
              showClose: true,
            })
          })
        } else {
          await method(arr).then((res) => {
            ElMessage({
              message: res.data.message,
              type: 'success',
              duration: 5000,
              plain: true,
              showClose: true,
            })
            if (dialog != '') {
              dialog.value = false
            }
          })
        }
        selecttion.value = []
        tableDom.value.clearSelection()
        getList()
      })
      .catch(() => {
        if (obj.column.label == '查询条件') {
          obj.row.listCondition = !obj.row.listCondition
        }
        if (obj.column.label == '列表显示') {
          obj.row.listShow = !obj.row.listShow
        }
        if (obj.column.label == '移动端显示') {
          obj.row.mobileShow = !obj.row.mobileShow
        }
      })
  }

  // 修改字段状态
  const changeAll = (n) => {
    if (n == 1) {
      changeMethod('启用', disableField, selecttion.value, false, '', '')
    }
    if (n == 2) {
      changeMethod('禁用', disableField, selecttion.value, true, '', '')
    }
    if (n == 3) {
      changeMethod('删除', deleteField, selecttion.value, 3, '', '')
    }
    if (n == 33) {
      changeMethod('删除', deleteField, [form.id], 3, addDialog, '')
    }
    // false-不显示，true-显示
    if (n == 4) {
      changeMethod('更改', listConditionField, selecttion.value, true, '', '')
    }
    if (n == 5) {
      changeMethod('更改', listConditionField, selecttion.value, false, '', '')
    }
    if (n == 6) {
      changeMethod('更改', listShowField, selecttion.value, true, '', '')
    }
    if (n == 7) {
      changeMethod('更改', listShowField, selecttion.value, false, '', '')
    }
    if (n == 8) {
      changeMethod('更改', mobileShowField, selecttion.value, true, '', '')
    }
    if (n == 9) {
      changeMethod('更改', mobileShowField, selecttion.value, false, '', '')
    }
  }

  // 显示状态改变前判断
  const beforeSwitchChange = () => {
    switchState.switchStatus = true
    return switchState.switchStatus
  }

  // 显示状态改变时
  const changeShow = (val, obj) => {
    if (switchState.switchStatus) {
      if (obj.column.label == '查询条件') {
        changeMethod('更改', listConditionField, [obj.row.id], val, '', obj)
      }
      if (obj.column.label == '列表显示') {
        changeMethod('更改', listShowField, [obj.row.id], val, '', obj)
      }
      if (obj.column.label == '移动端显示') {
        changeMethod('更改', mobileShowField, [obj.row.id], val, '', obj)
      }
    }
  }

  // 返回方法
  defineExpose({ getList })
</script>

<style scoped lang="scss">
  @import './CodeCustomField.scss';
</style>
